package com.yfbao.horizon.service;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class CtpClassLoader  extends ClassLoader{
    public static final Logger log = LoggerFactory.getLogger(CtpClassLoader.class);
    private String classPath;
    private Class<?> aClass;
    private InputStream inputStream;
    private String fileName;
//    private  byte[] cLassBytes;

    public CtpClassLoader(String classPath){
        this.classPath = classPath;
    }

    public CtpClassLoader(String fileName,InputStream inputStream){
        this.fileName = fileName;
        this.inputStream = inputStream;
    }

    public Collection<String> getFieldValue(String fieldName){
        List<String> list = new ArrayList<>();
        try {
            if(aClass ==null ){
                aClass = findClass(fileName);
            }
            if(inputStream!=null){
                inputStream.close();
            }
            Object obj = this.aClass.newInstance();
            Field[] declaredFields = this.aClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
                if(declaredField.getName().equals(fieldName)){
                    Object o = declaredField.get(obj);
                    if(o instanceof Collection){
                        Collection o1 = (Collection) o;
                        return o1;
                    }
                    log.error("无法识别calss="+ this.aClass.getName());
                }
            }
        } catch (Throwable e) {
            log.error("获取jar中class:"+classPath+"的属性："+fieldName+"异常",e);
        }
        return list;
    }


    /**
     * 读取.class文件
     */
    @Override
    protected Class<?> findClass(String className)
            throws ClassNotFoundException {
        byte[] cLassBytes =new byte[0];
            try {
                if(classPath!=null){
                    Path path = Paths.get(new URI("file:///"+this.classPath));
                    cLassBytes = Files.readAllBytes(path);
                }else if(inputStream!=null){
                    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                    byte[] buffer = new byte[1024];
                    int len = -1;
                    while((len=inputStream.read(buffer))!=-1){
                        outStream.write(buffer,0,len);
                    }
                    outStream.close();
                    inputStream.close();
                    cLassBytes =  outStream.toByteArray();
                }else {
                    log.error("解析"+fileName+".class异常");
                }
            } catch (IOException | URISyntaxException e) {
                e.printStackTrace();
            }
        Class cLass = defineClass(null,cLassBytes, 0, cLassBytes.length);
        return cLass;
    }

    /**
     * 读取.class文件
     */
    protected Class<?> findClass(InputStream inputStream){
        byte[] cLassBytes = new byte[0];
        try {
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = -1;
            while((len=inputStream.read(buffer))!=-1){
                outStream.write(buffer,0,len);
            }
            outStream.close();
//            inputStream.close();
            inputStream.reset();
            cLassBytes =  outStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Class cLass = defineClass(null,cLassBytes, 0, cLassBytes.length);
        return cLass;
    }

}
